home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / GLE / transport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  10.6 KB  |  380 lines

  1. /* 
  2.  * transport.c
  3.  * 
  4.  * FUNCTION:
  5.  * Illustrate principle of shearing vs. parallel transport.
  6.  *
  7.  * HISTORY:
  8.  * -- created by Linas Vepstas October 1991
  9.  * -- C++ and OO playing around Linas Vepstas June 1993
  10.  * -- converted to use GLUT -- December 1995, Linas
  11.  *
  12.  */
  13.  
  14. /* required include files */
  15. #include <stdlib.h>
  16. #include <math.h>
  17. #include <GL/glut.h>
  18. #include <GL/tube.h>
  19.  
  20. /* =========================================================== */
  21.  
  22. #define SET_RGB(rgb,r,g,b) {            \
  23.     rgb[0]=r; rgb[1]=g; rgb[2]=b;        \
  24.  
  25. typedef struct _material {
  26.  
  27.    /* public data areas */
  28.    float emission[3];    
  29.    float ambient[3];  
  30.    float diffuse[3];  
  31.    float specular[3]; 
  32.    float shininess;
  33.  
  34. } Material;
  35.  
  36. #define SET_EMIS(self,r,g,b) { SET_RGB(self->emission, r,g,b); }
  37. #define SET_AMB(self,r,g,b) { SET_RGB(self->ambient, r,g,b); }
  38. #define SET_DIFF(self,r,g,b) { SET_RGB(self->diffuse, r,g,b); }
  39. #define SET_SPEC(self,r,g,b) { SET_RGB(self->specular, r,g,b); }
  40.  
  41. /* =========================================================== */
  42.  
  43. #ifdef NOTNOW
  44. class goPolyline {
  45.    public:
  46.       int dimension;
  47.       int numPoints;
  48.       double * pts;
  49.  
  50.    private:
  51.       int  nfree;
  52.  
  53.    public:
  54.       goPolyline ();        // by default, construct 3D polyline
  55.       goPolyline (int);            // construct arbitrary dimension polyline
  56.       void Print ();
  57.       void AddPoint (double x, double y);
  58.       void AddNormal (double x, double y);
  59.       void MakeFacetNormal ();
  60. };
  61. #endif /* NOTNOW */
  62.  
  63. typedef double SVec[2];
  64.  
  65. typedef struct contour {
  66.  
  67.    /* public data areas */
  68.    int numContourPoints;
  69.    int numContourNorms;
  70.    SVec * pts;
  71.    SVec * norms;
  72.    double up[3];
  73.  
  74. } Contour;
  75.  
  76. #define pfree numContourPoints
  77. #define nfree numContourNorms
  78.  
  79. #define NEW_CONTOUR(self) {            \
  80.    self -> pts = (SVec *) malloc (100*sizeof (double));    \
  81.    self -> norms = (SVec *) malloc (100*sizeof (double));    \
  82.    self -> pfree = 0;        \
  83.    self -> nfree = 0;        \
  84. }
  85.  
  86. #define ADD_POINT(self,x,y) {             \
  87.    self -> pts[self->pfree][0] = x;        \
  88.    self -> pts[self->pfree][1] = y;        \
  89.    self->pfree ++;                \
  90. }
  91.  
  92. #define ADD_NORMAL(self,x,y) {             \
  93.    self -> norms[self->nfree][0] = x;        \
  94.    self -> norms[self->nfree][1] = y;        \
  95.    self->nfree ++;                \
  96. }
  97.  
  98. #define MAKE_NORMAL(self) {            \
  99.    float dx, dy, w;                \
  100.    dx = self -> pts [self->pfree -1][0];    \
  101.    dx -= self -> pts [self->pfree -2][0];    \
  102.    dy = self -> pts [self->pfree -1][1];    \
  103.    dy -= self -> pts [self->pfree -2][1];    \
  104.    w = 1.0 / sqrt (dx*dx+dy*dy);        \
  105.    dx *= w;                    \
  106.    dy *= w;                    \
  107.    self -> norms[self->nfree][0] = -dy;        \
  108.    self -> norms[self->nfree][1] = dx;        \
  109.    self -> nfree ++;                \
  110. }
  111.  
  112. /* =========================================================== */
  113. /* class gleExtrustion */
  114.  
  115. typedef struct _extrusion {
  116.    Material    *material;    /* material description */
  117.    Contour     *contour;    /* 2D contour */
  118.  
  119.    double radius;        /* for polycylinder, torus */
  120.    double startRadius;     /* spiral starts in x-y plane */
  121.    double drdTheta;        /* change in radius per revolution */
  122.    double startZ;          /* starting z value */
  123.    double dzdTheta;        /* change in Z per revolution */
  124.    double startXform[2][3]; /* starting contour affine xform */
  125.    double dXdTheta[2][3]; /* tangent change xform per revoln */
  126.    double startTheta;      /* start angle in x-y plane */
  127.    double sweepTheta;     /* degrees to spiral around */
  128.  
  129. } Extrusion;
  130.  
  131. #define  NEW_EXTRUSION(self) {        \
  132.    self -> material = (Material *) malloc (sizeof (Material));    \
  133.    self -> contour = (Contour *) malloc (sizeof (Contour));    \
  134.    NEW_CONTOUR (self->contour);                    \
  135. }
  136.     
  137.  
  138. /* =========================================================== */
  139. Extrusion *arrow = NULL;
  140.  
  141. /* =========================================================== */
  142. float lastx=0;
  143. float lasty=0;
  144.  
  145. void draw_arrow () {
  146.  
  147.    /* attach the mouse */
  148.    arrow->sweepTheta = 180.0 + 0.13* lastx;
  149.    arrow->dzdTheta = 0.03 * (lasty+10.0);
  150.  
  151.    glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, arrow->material->ambient);
  152.    glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, arrow->material->diffuse);
  153.    glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, arrow->material->specular);
  154.    glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 2.0);
  155.  
  156. #ifdef IBM_GL_32
  157.    rotate (-750, 'x');
  158.    rotate (-100, 'z');
  159.  
  160.    /* first, draw with the routine that uses a local coordinate 
  161.     * system with torsion */
  162.    translate (-0.5, -0.5, 3.2);
  163.  
  164.    lathe (arrow->contour->numContourPoints,
  165.            arrow->contour->pts,
  166.            arrow->contour->norms,
  167.            arrow->contour->up,
  168.            arrow->startRadius,    /* donut radius */
  169.            arrow->drdTheta,   /* change in donut radius per revolution */
  170.            arrow->startZ,    /* start z value */
  171.            arrow->dzdTheta,     /* change in Z per revolution */
  172.            NULL,
  173.            NULL,
  174.            arrow->startTheta,     /* start angle */
  175.            arrow->sweepTheta);     /* sweep angle */
  176.  
  177.    draw_axes ();
  178.  
  179.    /* next, draw with a routine that uses parallel transport */
  180.    translate (0.0, 0.0, -5.4);
  181.    lmbind (MATERIAL, 88);
  182.    cpack (0x339999);
  183.    spiral (arrow->contour->numContourPoints,
  184.            arrow->contour->pts,
  185.            arrow->contour->norms,
  186.            arrow->contour->up,
  187.            arrow->startRadius,    /* donut radius */
  188.            arrow->drdTheta,   /* change in donut radius per revolution */
  189.            arrow->startZ,    /* start z value */
  190.            arrow->dzdTheta,     /* change in Z per revolution */
  191.            NULL,
  192.            NULL,
  193.            arrow->startTheta,     /* start angle */
  194.            arrow->sweepTheta);     /* sweep angle */
  195.  
  196. #endif 
  197.  
  198. #define OPENGL_10
  199. #ifdef OPENGL_10
  200.    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  201.  
  202.    /* set up some matrices so that the object spins with the mouse */
  203.    glPushMatrix ();
  204.    glTranslatef (0.0, 0.0, -80.0);
  205.    glRotated (-75.0, 1.0, 0.0, 0.0);
  206.    glRotated (-10.0, 0.0, 0.0, 1.0);
  207.  
  208.    /* first, draw with the routine that uses a local coordinate 
  209.     * system with torsion */
  210.    glTranslated (-0.5, -0.5, 4.2);
  211.  
  212.    gleLathe (arrow->contour->numContourPoints,
  213.            arrow->contour->pts,
  214.            arrow->contour->norms,
  215.            arrow->contour->up,
  216.            arrow->startRadius,    /* donut radius */
  217.            arrow->drdTheta,   /* change in donut radius per revolution */
  218.            arrow->startZ,    /* start z value */
  219.            arrow->dzdTheta,     /* change in Z per revolution */
  220.            NULL,
  221.            NULL,
  222.            arrow->startTheta,     /* start angle */
  223.            arrow->sweepTheta);     /* sweep angle */
  224.  
  225.    /* next, draw with a routine that uses parallel transport */
  226.    glTranslated (0.0, 0.0, -8.4);
  227. /*
  228.    lmbind (MATERIAL, 88);
  229.    cpack (0x339999);
  230. */
  231.    gleSpiral (arrow->contour->numContourPoints,
  232.            arrow->contour->pts,
  233.            arrow->contour->norms,
  234.            arrow->contour->up,
  235.            arrow->startRadius,    /* donut radius */
  236.            arrow->drdTheta,   /* change in donut radius per revolution */
  237.            arrow->startZ,    /* start z value */
  238.            arrow->dzdTheta,     /* change in Z per revolution */
  239.            NULL,
  240.            NULL,
  241.            arrow->startTheta,     /* start angle */
  242.            arrow->sweepTheta);     /* sweep angle */
  243.  
  244.    glPopMatrix ();
  245.    glutSwapBuffers ();
  246. #endif 
  247. }
  248.  
  249. /* =========================================================== */
  250.  
  251. #define SCALE 1.80
  252. #define PT(x,y) { ADD_POINT (arrow->contour, SCALE*x, SCALE*y); }
  253. #define NORM(x,y) { ADD_NORMAL (arrow->contour, x, y); }
  254. #define FACET { MAKE_NORMAL (arrow->contour); }
  255.  
  256. /* =========================================================== */
  257.  
  258. void init_arrow (void)
  259. {
  260.    int style;
  261.  
  262.    arrow = (Extrusion *) malloc (sizeof (Extrusion));
  263.    NEW_EXTRUSION (arrow);
  264.  
  265.    /* define color of arrow */
  266.    SET_AMB (arrow->material, 0.15, 0.15, 0.15);
  267.    SET_DIFF (arrow->material, 0.15, 0.55, 0.55);
  268.    SET_SPEC (arrow->material, 0.4, 0.4, 0.4);
  269.  
  270.    /* define lathe/spiral parameters */
  271.    arrow -> startRadius = 7.3;
  272.    arrow -> drdTheta = 0.0;
  273.    arrow -> startZ = 0.0;
  274.    arrow -> dzdTheta = 0.0;
  275.    arrow -> startTheta = 0.0;
  276.    arrow -> sweepTheta = 90.0;
  277.  
  278.    /* define arrow contour */
  279.    PT (-1.0, -2.0); 
  280.    PT (-1.0, 0.0); FACET; 
  281.    PT (-2.0, 0.0); FACET;
  282.    PT (0.0, 2.0); FACET;
  283.    PT (2.0, 0.0); FACET;
  284.    PT (1.0, 0.0); FACET;
  285.    PT (1.0, -2.0); FACET;
  286.  
  287.    /* define contour up vector */
  288.    arrow->contour->up[0] = 0.0;
  289.    arrow->contour->up[1] = 0.0;
  290.    arrow->contour->up[2] = 1.0;
  291.  
  292.    /* set the initial join style */
  293.    style = 0x0;
  294.    style |= TUBE_JN_CAP;
  295.    style |= TUBE_NORM_PATH_EDGE;
  296.    style |= TUBE_NORM_FACET;
  297.    style |= TUBE_CONTOUR_CLOSED;
  298.    gleSetJoinStyle (style);
  299.  
  300. }
  301.  
  302. /* =========================================================== */
  303.  
  304. /* get notified of mouse motions */
  305. void MouseMotion (int x, int y)
  306. {
  307.    lastx = x;
  308.    lasty = y;
  309.    glutPostRedisplay ();
  310. }
  311.  
  312. /* ARGSUSED */
  313. void JoinStyle (int msg) 
  314. {
  315.    exit (0);
  316. }
  317.  
  318. /* set up a light */
  319. GLfloat lightOnePosition[] = {40.0, 40, 100.0, 0.0};
  320. GLfloat lightOneColor[] = {0.54, 0.54, 0.54, 1.0}; 
  321.  
  322. GLfloat lightTwoPosition[] = {-40.0, 40, 100.0, 0.0};
  323. GLfloat lightTwoColor[] = {0.54, 0.54, 0.54, 1.0}; 
  324.  
  325. GLfloat lightThreePosition[] = {40.0, 40, -100.0, 0.0};
  326. GLfloat lightThreeColor[] = {0.54, 0.54, 0.54, 1.0}; 
  327.  
  328. int
  329. main (int argc, char * argv[]) {
  330.  
  331.    /* initialize glut */
  332.    glutInit (&argc, argv);
  333.    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  334.    glutCreateWindow ("transport");
  335.    glutDisplayFunc (draw_arrow);
  336.    glutMotionFunc (MouseMotion);
  337.  
  338.    /* create popup menu */
  339.    glutCreateMenu (JoinStyle);
  340.    glutAddMenuEntry ("Exit", 99);
  341.    glutAttachMenu (GLUT_MIDDLE_BUTTON);
  342.  
  343.    /* initialize GL */
  344.    glClearDepth (1.0);
  345.    glEnable (GL_DEPTH_TEST);
  346.    glClearColor (0.0, 0.0, 0.0, 0.0);
  347.    glShadeModel (GL_SMOOTH);
  348.  
  349.    glMatrixMode (GL_PROJECTION);
  350.    /* roughly, measured in centimeters */
  351.    glFrustum (-9.0, 9.0, -9.0, 9.0, 50.0, 150.0);
  352.    glMatrixMode(GL_MODELVIEW);
  353.  
  354.    /* initialize lighting */
  355.    glLightfv (GL_LIGHT0, GL_POSITION, lightOnePosition);
  356.    glLightfv (GL_LIGHT0, GL_AMBIENT, lightOneColor);
  357.    glLightfv (GL_LIGHT0, GL_DIFFUSE, lightOneColor);
  358.    glLightfv (GL_LIGHT0, GL_SPECULAR, lightOneColor);
  359.    glEnable (GL_LIGHT0);
  360.    glLightfv (GL_LIGHT1, GL_POSITION, lightTwoPosition);
  361.    glLightfv (GL_LIGHT1, GL_DIFFUSE, lightTwoColor);
  362.    glLightfv (GL_LIGHT1, GL_AMBIENT, lightTwoColor);
  363.    glEnable (GL_LIGHT1);
  364.    glLightfv (GL_LIGHT2, GL_POSITION, lightThreePosition);
  365.    glLightfv (GL_LIGHT2, GL_DIFFUSE, lightThreeColor);
  366.    glLightfv (GL_LIGHT2, GL_AMBIENT, lightThreeColor);
  367.    glEnable (GL_LIGHT2);
  368.    glEnable (GL_LIGHTING);
  369.    glEnable (GL_NORMALIZE);
  370.    /* glColorMaterial (GL_FRONT_AND_BACK, GL_DIFFUSE); */
  371.    /* glEnable (GL_COLOR_MATERIAL); */
  372.  
  373.    init_arrow ();
  374.  
  375.    glutMainLoop ();
  376.    return 0;             /* ANSI C requires main to return int. */
  377. }
  378. /* ================== END OF FILE ================== */
  379.